package com.funwell.server.interceptor;


import com.funwell.modules.model.user.User;
import com.funwell.modules.service.user.UserSessionService;
import com.funwell.server.annotation.ACS;
import com.funwell.server.constants.Errors;
import com.funwell.server.utils.ExceptionUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;


/**
 * 权限控制拦截器.
 *
 * @author leihe@uworks.cc
 */
@Component
public class AccessControlInterceptor extends HandlerInterceptorAdapter {
  
  @Resource
  protected UserSessionService userSessionService;

  private static final List<String> noLoginResources = new ArrayList<String>() {
    private static final long serialVersionUID = 1L;

    {
      // swagger相关资源不需要登录
      add("/swagger-ui.html");
      add("/configuration");
      add("/swagger-resources");
      add("/api-docs");
      add("/v2/api-docs");
      add("/user/register");
      add("/user/login");
      add("/user/aboutUs");
      add("/user/userGuide");
      add("/sms/*");
      add("/cache");
      add("/cache/*");
      add("/error");
    }
  };

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 不需要进行访问控制的资源过滤
    String uri = request.getRequestURI();
    for (String resource : noLoginResources) {
      if (uri.startsWith(resource)) {
        return true;
      }
    }
    if (handler instanceof HandlerMethod) {
      ACS acs = ((HandlerMethod) handler).getMethodAnnotation(ACS.class);
      // 判断是否允许匿名访问
      if (acs != null && acs.allowAnonymous()) {
        return true;
      }
    }
    // 缓存获取验证
    User user = userSessionService.getSessionUser(request);
    if (user == null) {
      ExceptionUtil.throwException(Errors.SYSTEM_NOT_LOGIN);
    }
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
      throws Exception {}

}
